package com.rivues.module.manage.web.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import org.apache.commons.lang.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Sheet;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Restrictions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.rivues.core.RivuDataContext;
import com.rivues.module.platform.web.model.Role;
import com.rivues.module.platform.web.model.RoleGroup;
import com.rivues.module.platform.web.model.User;
import com.rivues.module.platform.web.model.UserOrgan;
import com.rivues.module.platform.web.model.UserRole;
import com.rivues.util.RivuTools;
import com.rivues.util.iface.authz.UserAuthzFactory;
/**
 * 账号处理service
 * @author leon
 */
@Service
public class AccountServiceImpl extends AccountServiceAbs implements AccountService {
	/**
	 * log4j
	 */
	private final Logger logger = LoggerFactory.getLogger(AccountServiceImpl.class);
	/**
	 * 导入实现
	 * @param sheet
	 * @param orgi
	 * @param creater
	 * @throws Exception
	 */
	protected List<String> processImport(HSSFWorkbook workbook,String orgi,String creater) throws Exception{
//		this.processOrganImport(workbook.getSheetAt(0), orgi, creater);
//		this.processRoleImport(workbook.getSheetAt(1), orgi, creater);
		return this.processUserImport(workbook.getSheetAt(0), orgi, creater);
	}
	
	
	/**
	 * 处理用户角色导入
	 * @param sheet
	 * @param orgi
	 * @param creater
	 * @throws Exception
	 */
	private void processRoleImport(Sheet sheet ,String orgi,String creater) throws Exception{
		if(sheet == null)return;
		List<Role> roleList = new ArrayList<Role>();
		logger.info("导入角色开始，sheet包含组织数量为:"+sheet.getLastRowNum());
		for (int i = 2; i <= sheet.getLastRowNum(); i++) {
			String roleName = getStringCellValue(sheet.getRow(i).getCell(0));
			if (StringUtils.isBlank(roleName)) continue;
			String desc =  getStringCellValue(sheet.getRow(i).getCell(1));
			Role role = new Role();
			role.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			role.setCreater(creater);
			role.setOrgi(orgi);
			role.setCreatetime(new Date());
			role.setName(roleName);
			role.setDescription(desc);
			roleList.add(role);
		}
		if(roleList.isEmpty()) return;
		logger.info("角色导入格式校验完成，开始进行逻辑校验，数据量为:"+roleList.size());
		//获取所有角色，不用循环调用，增加性能
		Map<String, Role> map = new HashMap<String, Role>();
		if(roleList.size() >10) map = getAllRole(orgi);
		List<Role> insertList = new ArrayList<Role>();
		for(Role tmp : roleList){
			if (map.size()>0 && map.containsKey(tmp.getName())){
				insertList.add(tmp);
				map.put(tmp.getName(), tmp);
			} else {
				List<Role> tmpList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Role.class).add(Restrictions.eq("name", tmp.getName())).add(Restrictions.eq("orgi",tmp.getOrgi())));
				if(tmpList.size()>0) continue;
				insertList.add(tmp);
			}
		}
		
		logger.info("角色导入逻辑校验完成，新增数据量为:"+insertList.size());
		if(insertList.size()>0) RivuDataContext.getService().saveBat(insertList);
		
	}
	
	/**
	 * 处理组织机构导入
	 * @param sheet
	 * @param orgi
	 * @throws Exception
	 */
	/*private void processOrganImport(Sheet sheet ,String orgi,String creater) throws Exception{
		if(sheet == null) return;
		List<Organ> organList = new ArrayList<Organ>();
		logger.info("导入组织开始，sheet包含组织数量为:"+sheet.getLastRowNum());
		List<String> distinctList = new ArrayList<String>();
		for (int i = 2; i <= sheet.getLastRowNum(); i++) {
			String organName = getStringCellValue(sheet.getRow(i).getCell(0));
			String organCode = getStringCellValue(sheet.getRow(i).getCell(1));
			String parentName = getStringCellValue(sheet.getRow(i).getCell(2));
			String parentCode = getStringCellValue(sheet.getRow(i).getCell(3));
			if (StringUtils.isBlank(organName) || StringUtils.isBlank(organCode) || StringUtils.isBlank(parentCode)) continue;
			String parentOrgan = getStringCellValue(sheet.getRow(i).getCell(1));
			parentOrgan = StringUtils.isBlank(parentOrgan) ? "0" : parentOrgan;
			//如果本sheet中存在重复，则过滤
			if (distinctList.contains(organName+parentOrgan))continue;
			Organ organ = new Organ();
			organ.setId(UUID.randomUUID().toString().replaceAll("-", ""));
			organ.setCreatetime(new Date());
			organ.setName(organName);
			organ.setOrgi(orgi);
			organ.setParentid(parentOrgan);
			organ.setCreater(creater);
			organList.add(organ);
		}
		//释放内存
		distinctList.clear();
		
		logger.info("组织导入格式校验完成，组织数量为:"+organList.size()+",开始进行逻辑校验 ");
		if (organList.isEmpty()) return;
		//如果过滤后的组织数据大于10，则一次性取出所有组织信息
		List<Organ> insertList = new ArrayList<Organ>();
		//逻辑过滤
		for(Organ organ : organList){
			//判断名字是否重复
			List<Organ> tmpList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Organ.class).add(Restrictions.eq("name", organ.getName())).add(Restrictions.eq("orgi", organ.getOrgi())));
			if(tmpList!= null && tmpList.size()>0) continue;
			if ("0".equals(organ.getParentid())) {
				//如果上级组织为根组织，不用校验根组织是否存在
				insertList.add(organ);
			} else {
				//如果上级组织不为根组织,判断上级组织是否存在
				tmpList = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Organ.class).add(Restrictions.eq("name", organ.getParentid())).add(Restrictions.eq("orgi", organ.getOrgi())));
				if(tmpList!= null && tmpList.isEmpty()) continue;
				insertList.add(organ);
			}
		}
		logger.info("导入组织逻辑校验结束，新增数量为:"+insertList.size());
		//批量写入
		if (insertList.size()>0) RivuDataContext.getService().saveBat(insertList);
	}*/

	/**
	 * 处理用户导入
	 * @param sheet
	 * @param orgi
	 * @throws Exception
	 */
	private List<String> processUserImport(Sheet sheet,String orgi,String creater ) throws Exception{
		List<String> users = new ArrayList<String>();
		if (sheet == null) return users;
		
		logger.info("导入用户开始，sheet包含用户数量为:"+sheet.getLastRowNum());
		for (int i = 2; i <= sheet.getLastRowNum(); i++) {
			// 登录名
			String loginname = getStringCellValue(sheet.getRow(i).getCell(0));
			User user = new User();
			String username = getStringCellValue(sheet.getRow(i).getCell(1));
			String email = getStringCellValue(sheet.getRow(i).getCell(3));
			int count = RivuDataContext.getService().getCountByCriteria(DetachedCriteria.forClass(User.class).add(Restrictions.eq("organ",loginname)).add(Restrictions.eq("orgi",orgi)));
			if (StringUtils.isBlank(loginname)||StringUtils.isBlank(username)||StringUtils.isBlank(email)||count>0) {
				users.add(loginname);
				continue;
			}
			
			user.setNickname(username);
			user.setFirstname(username);
			user.setEmail(email);
			user.setUsername(loginname);
			user.setCreater(creater);
			user.setCreatetime(new Date());	
			user.setOrgi(orgi);
			user.setMobile(getStringCellValue(sheet.getRow(i).getCell(5)));
			String password = getStringCellValue(sheet.getRow(i).getCell(2));
			if(StringUtils.isBlank(password)){
				user.setPassword(RivuTools.md5("123456"));
			}else{
				user.setPassword(RivuTools.md5(password.trim()));
			}
			
			RivuDataContext.getService().saveIObject(user);
			UserOrgan ur = new UserOrgan();
			ur.setOrganid("0");
			ur.setOrgi(orgi);
			ur.setUserid(user.getId());
			RivuDataContext.getService().saveIObject(ur);
			// 用户角色
			String cellValue = getStringCellValue(sheet.getRow(i).getCell(6));
			Role role= this.getRole(cellValue, orgi, creater);
			
			if(role!=null){
				UserRole userrole = new UserRole();
				userrole.setOrgi(orgi);
				userrole.setRoleid(role.getId());
				userrole.setUserid(user.getId());
				RivuDataContext.getService().saveIObject(userrole);
			}
			
		}
		return users;
	}
	
	private Role getRole(String roleStr,String orgi,String creater){
		Role role  = null;
		
		if (roleStr==null||"".equals(roleStr)||"/".equals(roleStr)) return role;
		if(roleStr.startsWith("/")){
			roleStr = roleStr.substring(1, roleStr.length());
		}
		
		String[] roles = roleStr.split("/");
		
		List<RoleGroup> groups = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(RoleGroup.class).add(Restrictions.eq("orgi",orgi)));
		String parent = "0" ;
		RoleGroup group = null;
		for (int i = 0; i < roles.length; i++) {
			
			if(i==roles.length-1){
				List<Role> rolelist = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Role.class).add(Restrictions.eq("groupid",parent)).add(Restrictions.eq("name",roles[i])).add(Restrictions.eq("orgi",orgi)));
				if(rolelist.size()>0){
					role = rolelist.get(0);
				}else{
					role = new Role();
					role.setCreater(creater);
					role.setCreatetime(new Date());
					role.setGroupid(parent);
					role.setOrgi(orgi);
					role.setName(roles[i]);
					role.setUpdatetime(new Date());
					RivuDataContext.getService().saveIObject(role);
				}
			}else if(i==0){
				group = this.getRoleGroup(roles[i], "0", groups);
			}else{
				group = this.getRoleGroup(roles[i], group.getId(), groups);
			}
			//如果没检索到创建分组
			if(group==null&&role==null){
				group = new RoleGroup();
				group.setCreater(creater);
				group.setCreatetime(new Date());
				group.setName(roles[i]);
				group.setOrgi(orgi);
				group.setParentid(parent);
				RivuDataContext.getService().saveIObject(group);
			}
			if(group!=null){
				parent = group.getId();
			}
			
		}
		return role;
	}
	/**
	 * 查询数据库里存不存在相应的角色
	 * @param name
	 * @param parentId
	 * @param groups
	 * @return
	 */
	private RoleGroup getRoleGroup(String name,String parentId,List<RoleGroup> groups){
		RoleGroup group = null;
		for (int i = 0; i < groups.size(); i++) {		
			if(groups.get(i).getName().equals(name)&&groups.get(i).getParentid().equals(parentId)){
				group = groups.get(i);
				break;
			}
		}
		return group;
	}
	/**
	 * 新增角色
	 * @param roleMap
	 * @param orgi
	 * @return
	 */
	private Map<String, String> addRoles(Map<String, Role> roleMap,String orgi ){
		List<Role> addList = new ArrayList<Role>();
		 Map<String, String> returnMap = new HashMap<String, String>();
		for(String roleName :  roleMap.keySet()){
			List<Role> list = RivuDataContext.getService().findAllByCriteria(DetachedCriteria.forClass(Role.class).add(Restrictions.eq("name", roleName)).add(Restrictions.eq("orgi", orgi)));
			if(list != null && list.size() >0) {
				returnMap.put(roleName, list.get(0).getId());
				continue;
			}
			addList.add(roleMap.get(roleName));
			returnMap.put(roleName, roleMap.get(roleName).getId());
		}
		if(addList.size()>0)RivuDataContext.getService().saveBat(addList);
		return returnMap;
	}
	
	
	
}
